#ifndef _CAR_H
#define _CAR_H

#include "fixed.h"
 
#define SERVO_PERIOD 20000			// a pulse will be sent every 20,000us = 20ms
#define SERVO_CENTER 1480           // a pulse width of 1500us will center the servo
#define SERVO_SCALE 300				// maximum/minimum pulse width

#define MOTOR_PERIOD 10000			// period of motor PWM cyle in ms. Want 100Hz
#define MOTOR_MAX 0.10				// set the max speed of the motor in the range [0, 1.0]

// event fired when the servo needsto be updated. The callee
// should then call servo_set() to update the servo position
typedef void (*servo_func)(void);

// initiailize the servo. The servo will center.
void servo_init(void);

// returns TRUE if the servo is ready for a new value. This function returns
// true immediately after the pulse goes high. After a new value is set
// using servo_set(), this function will return false until the next cycle.
int servo_ready(void);

// set the angle of the servo in the range [-1, 1],
// where -1 is hard left and +1 is hard right
void servo_set(fixedp pos);

void servo_set_callback(servo_func func);

// get the current position of the servo
fixedp servo_get();

typedef enum {
	coast,
	accel,
	brake
} motor_mode;

// initialize the motor
void motor_init();

// set the speed of the motor or brake
// speed should be in the range [0, 1.0]. When mode is "accel", speed sets
// the acceleration of the car where 0 is no acceleration and
// 1.0 is scaled to MOTOR_MAX to be the maximum acceleration. When mode is "brake",
// the acceleration is set to 0 and speed controls the intensity of the braking.
// values out of the range are clamped to the range [0, 1.0]
// mode determines whether the car is in acceleration mode, brake mode, or coast mode.
// In coast mode, neither acceleration nor brakes are applied
void motor_set(fixedp speed, motor_mode mode);

// get the current state of the motor
// speed is in Q2.30 format
void motor_get(fixedp *speed, motor_mode *mode);

#endif // _CAR_H
